package com.spi.soconversion.util;

import java.io.File;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;

import com.spi.soconversion.base.SOCException;

public class SOCUtility {

	private static Pattern numPattern = Pattern.compile("\\d+?");
	private static SimpleDateFormat dateTimeFormatter= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss a");
	private static SimpleDateFormat dateFormatter= new SimpleDateFormat("yyyy-MM-dd");
	private static SimpleDateFormat existingDateTimeFormatter= new SimpleDateFormat("yyyy/MM/dd mm:HH:ss");
	public static StringBuilder getAttribute(String attributeName, String attributeValue)
	{
		StringBuilder sb = new StringBuilder();
		sb.append(attributeName);
		sb.append(SOCConstants.EQUALS);
		sb.append(SOCConstants.DOUBLE_QUOTE);
		sb.append(attributeValue);
		sb.append(SOCConstants.DOUBLE_QUOTE);
		return sb;
	}
		
	/**
	 * Write the XML Document into XML File
	 * 
	 * @param doc
	 * @param filename
	 */
	public static void writeXmlFile(Document doc, String filename) 
	throws SOCException {        
        try {
            // Prepare the DOM document for writing
            Source source = new DOMSource(doc);

            // Prepare the output file
            File file = new File(filename);
            Result result = new StreamResult(file);
            
            // Write the DOM document to the file
            Transformer xformer = TransformerFactory.newInstance().newTransformer();
            xformer.setOutputProperty(OutputKeys.INDENT, "yes");
            xformer.transform(source, result);

        } catch (TransformerConfigurationException e) {
			throw new SOCException("Error in writing XML file.", e);
        } catch (TransformerException e) {
			throw new SOCException("Error in writing XML file.", e);
        } catch (Exception e) {
			throw new SOCException("Error in writing XML file.", e);
        }
	}	

	
	/**
	 * This method returns the string to be appended in xml file names.
	 * @return String - Return Format YYYY_MM_DD_HH_MM_SS String to be appended
	 *                  in file name
	 */
	public static String dateSuffix()
	{
		String result = (new Timestamp(new Date().getTime())).toString();

		// Find date
		int dateIndex = result.indexOf(SOCConstants.BLANK_STRING);
		// Find time
		int timeStartIndex = result.indexOf(SOCConstants.COLON);

		int timeEndIndex = result.indexOf(SOCConstants.DOT);

		String temp = result.substring(0, dateIndex);

		int tempIndex = temp.indexOf(SOCConstants.HYPHEN);

		String year = temp.substring(0, tempIndex);

		temp = temp.substring(tempIndex + 1);

		tempIndex = temp.indexOf(SOCConstants.HYPHEN);

		String month = temp.substring(0, tempIndex);

		String day = temp.substring(tempIndex + 1);

		result =
			year
				+ SOCConstants.UNDERSCORE
				+ month
				+ SOCConstants.UNDERSCORE
				+ day
				+ SOCConstants.UNDERSCORE
				+ result.substring(dateIndex + 1, timeStartIndex)
				+ SOCConstants.UNDERSCORE
				+ result.substring(timeStartIndex + 1, timeEndIndex - 3)
				+ SOCConstants.UNDERSCORE
				+ result.substring(timeStartIndex + 4, timeEndIndex);

		return result;
	}
	
	/**
	 * This method returns the string to be appended while appending log
	 * messages in log file.
	 * @return String - Return Format YYYY-MM-DD HH:MM:SS 
	 */
	private static String logFileDateSuffix()
	{
		String result = (new Timestamp(new Date().getTime())).toString();

		result = result.substring(0,result.indexOf("."));

		return result;
	}
	
	public static String writeLogMessage(String message)
	{
		String result = logFileDateSuffix()+ SOCConstants.BLANK_STRING+ message+SOCConstants.NEW_LINE;
		
		return result;
	}
	
	public  static boolean  checkDirectory(String dirName)
	{ 
		boolean result = false;
		
		File dirRef= new File(dirName);
		if (dirRef.exists())
        {
			result = true;
        }
		return result;
		
	}
	
	 public static int daysBetween(Date startDate, Date endDate){
	     
	     return (int)( (endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24));
	 }
	 
	 public static int getMonthDifference(Calendar fromCalendar, Calendar toCalendar) {
		 int count = 0;
		 for(fromCalendar.add(Calendar.MONTH, 1); fromCalendar.compareTo(toCalendar) <= 0; fromCalendar.add(
		 Calendar.MONTH, 1)) {
		 count++;
		 }
		 return count;
	}
		
	public  static String  checkNull(String value)
	{ 
		if (value != null && "null".equals(value)) {
			return value = "";
		}
		return value == null ? "" : value;
		
	}
	
	public static boolean isNumber(String value)
	{
		 boolean result= false;
		 Matcher matcher = numPattern.matcher(value);
		 result = matcher.matches();
		 
		 return result;
	}
	
	public static boolean createDirectory (String path)
	{
		boolean result = false;
		File dirRef= new File(path);
		result = dirRef.exists()? true: dirRef.mkdir();
		return result;
	}
	
	public static String getValidDate(String date)
	{
		Date dateObj = null;
		try 
	    { 
			dateObj = existingDateTimeFormatter.parse(date); 
	    } 
	 
	    // if the format of the string provided doesn't match the format we  
	    // declared in SimpleDateFormat() we will get an exception 
	 
	    catch (ParseException pe) 
	    { 
	       return null; 
	    } 
	   
	    if (!existingDateTimeFormatter.format(dateObj).equals(date))  
	    { 
	       return null; 
	    } 
	    return dateTimeFormatter.format(dateObj);
	}
	
	public static String formatDate (java.sql.Date date)
	{
		if(date!=null)
		{
			return dateTimeFormatter.format(date);
		}
		return null;
	}
	
	public static String formatDate (java.sql.Timestamp timeStamp)
	{		
		if(timeStamp!=null)
		{
			return dateTimeFormatter.format(timeStamp);
		}
		return "";
	}
	
	public static String replaceXMLSpecialCharacters (String data)
	{
		if(data!=null)
		{
			data=data.replaceAll("&","&amp;");
			data=data.replaceAll("<","&lt;");
			data=data.replaceAll(">","&gt;");
			data=data.replaceAll("\"","&quot;");
			data=data.replaceAll("'","&apos;");
			
		}
		return data;
	}
	
	public  static BigDecimal  checkNumberNull(BigDecimal value)
	{ 
		
		return value == null ? new BigDecimal("0") : value;
		
	}
	
	public  static BigDecimal  getDifference(BigDecimal  origAmt, BigDecimal  adjustedAmt)
	{
		origAmt=origAmt.subtract(adjustedAmt);
		origAmt=origAmt.setScale(2);
		return origAmt;
	}
	
	public static String removeNonBreakSpace(String data)
	{
		if(data!=null)
		{
			return data.replaceAll("[\\s\\u00A0]+$", "") ;
		}
		return data;
	}
	
	public static String getDate(String date)
	{
		Date dateObj = null;
		
		if(date==null || SOCConstants.EMPTY_STRING.equals(date))
		{
			return SOCConstants.EMPTY_STRING;
		}
		
		try 
	    { 
			dateObj = dateTimeFormatter.parse(date); 
	    } 
	 
	    // if the format of the string provided doesn't match the format we  
	    // declared in SimpleDateFormat() we will get an exception 
	 
	    catch (ParseException pe) 
	    { 
	       return null; 
	    } 
	   
	    if (!dateTimeFormatter.format(dateObj).equals(date))  
	    { 
	       return null; 
	    } 
	    return dateFormatter.format(dateObj);
	}
	
//	public static String addYearToDate(String date) {
	public static String addYearToDate(Timestamp timestamp) {
		if(timestamp==null || SOCConstants.EMPTY_STRING.equals(timestamp)) {
			return "";
		}
  
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(timestamp.getTime());
		cal.add(Calendar.YEAR, 1);	//Adding 1 year to date
		String newdate = dateTimeFormatter.format(cal.getTime());
		return newdate;
	}

	public static boolean compareDates(String date, boolean shipDate)
	{
		boolean result=false;
		
		if(date==null || SOCConstants.EMPTY_STRING.equals(date))
		{
			return false;
		}
		Date dateObj = null;
		try 
	    { 
			dateObj = dateFormatter.parse(date); 
	    } 
	 
	    // if the format of the string provided doesn't match the format we  
	    // declared in SimpleDateFormat() we will get an exception 
	 
	    catch (ParseException pe) 
	    { 
	    	  return false; 
	    } 
	 
		Calendar cal = Calendar.getInstance();
		
		Calendar compareToCal = Calendar.getInstance();
		
	    cal.setTimeInMillis(dateObj.getTime());
	    if(shipDate)
	    {
	    	compareToCal.set(2010,Calendar.JUNE,30);
	    }
	    else
	    {
	    	compareToCal.set(2010,Calendar.APRIL,30);
	    }
	  	    
	    if(cal.after(compareToCal))
	    {
	    	result=true;
		}
	    return result;
	    
	}
}
